#ifndef __PARSER_YAML_H__
#define __PARSER_YAML_H__

#include <yaml-cpp\node.h>
#include "yaml-cpp/yaml.h"
#include <fstream>
#include <iostream>

#include <string>
#include <list>

using namespace std;

#define YAML_NODO_RAIZ_INFO_CARRERA "carrera"
#define YAML_NODO_MATERIAS_OBLIGATORIAS "materias_obligatorias"
#define YAML_NODO_MATERIAS_OPTATIVAS "materias_optativas"

#define YAML_NODO_RAIZ_RESTRICCIONES_DETERMINISTICAS "restricciones_deterministicas"
#define YAML_NODO_MATERIAS_OPTATIVAS_A_CURSAR "optativas_que_quiero_cursar"
#define YAML_NODO_MATERIAS_OPTATIVAS_A_NO_CURSAR "optativas_que_no_quiero_cursar"
#define YAML_NODO_DISPONIBILIDAD_HORARIA "disponibilidad_horaria"

#define YAML_NODO_RAIZ_RESTRICCIONES_NO_DETERMINISTICAS "restricciones_no_deterministicas"

#define YAML_NODO_RAIZ_INFORMACION_MATERIAS "materias"
#define YAML_NODO_CATEDRAS "catedras"
#define YAML_NODO_DIAS_CURSADA "dias_cursada"

namespace parser {

	struct HoraYAML {
		int horas;
		int minutos;
	};

	struct DiaCursadaYAML {
		string diaDeLaSemana;
		HoraYAML horaDesde;
		HoraYAML horaHasta;
		string sede;
	};

	struct CatedraMateriaYAML {
		string descripcion;
		list<DiaCursadaYAML> diasCursada; 
	};

	struct InformacionMateriaYAML {
		string codigo;
		string nombre;
		int creditos;
		list<CatedraMateriaYAML> catedras;
	};

	struct InformacionMateriaSegunCarreraYAML {
		string codigo;
		string correlativas;
		bool esObligatoria;
	};

	struct InformacionCarreraYAML {
		string nombreCarrera;
		int creditosMateriasObligatorias;
		int creditosMateriasOptativas;
		int cantidadMateriasOptativas;
		list<InformacionMateriaSegunCarreraYAML> informacionMateriasObligatorias;
		list<InformacionMateriaSegunCarreraYAML> informacionMateriasOptativas;
	};

	struct DisponibilidadHorariaDiariaYAML {
		string dia;
		string horario;
	};
	
	struct InformacionRestriccionesDeterministicasYAML {
		int materiasMaximasPorCuatr;
		list<string> materiasOptativasACursar;
		list<string> materiasOptativasANoCursar;
		list<DisponibilidadHorariaDiariaYAML> disponibilidadHoraria;
	};

	struct InformacionRestriccionesNoDeterministicasYAML {
		int materiasDificultosasMaximasPorCuatrimestre;
		bool ajustarPlanAMateriasSinChequeoAsistencia;
		bool ajustarPlanOmitiendoOptativasPrescindibles;
	};

	class ParserYAML 
	{
	private:
		std::auto_ptr<YAML::Node> ObtenerNodoRaiz(string rutaArchivo, string raiz);

	public:
		ParserYAML(void);
		~ParserYAML(void);

		list<InformacionMateriaYAML> ParsearArchivoInformacionDeMaterias(string ruta);
		InformacionCarreraYAML ParsearArchivoInformacionDeCarrera(string ruta);
		InformacionRestriccionesDeterministicasYAML ParsearArchivoRestriccionesDeterministicas(string ruta);
		InformacionRestriccionesNoDeterministicasYAML ParsearArchivoRestriccionesNoDeterministicas(string ruta);
	};

}

#endif